﻿using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Linq.Expressions;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;

namespace Domain.RealiZation
{
    /// <summary>
    /// AutoMapper帮助类
    /// </summary>
    public static class AutoMapperHelper
    {
        /// <summary>
        ///  单个对象映射
        /// </summary>
        public static T MapTo<T>(this object obj)
        {
            if (obj == null) return default(T);
            AutoMapper.Mapper.Reset();
            AutoMapper.Mapper.Initialize(x => x.CreateMap(obj.GetType(), typeof(T)));
            return AutoMapper.Mapper.Map<T>(obj);
        }

        /// <summary>
        /// 集合列表类型映射
        /// </summary>
        public static List<TDestination> MapToList<TSource, TDestination>(this IEnumerable<TSource> source)
        {
            if (source == null) return null;
            AutoMapper.Mapper.Reset();
            AutoMapper.Mapper.Initialize(x => x.CreateMap<TSource, TDestination>());
            return AutoMapper.Mapper.Map<List<TDestination>>(source);
        }
    }
    //public static class AutoMapperHelper
    //{
    //    /// <summary>
    //    /// 同步锁
    //    /// </summary>
    //    private static readonly object Sync = new object();

    //    #region MapTo(将源对象映射到目标对象)

    //    /// <summary>
    //    /// 将源对象映射到目标对象
    //    /// </summary>
    //    /// <typeparam name="TSource">源类型</typeparam>
    //    /// <typeparam name="TDestination">目标类型</typeparam>
    //    /// <param name="source">源对象</param>
    //    /// <param name="destination">目标对象</param>
    //    /// <returns></returns>
    //    public static TDestination MapTo<TSource, TDestination>(this TSource source, TDestination destination)
    //    {
    //        return MapTo<TDestination>(source, destination);
    //    }

    //    /// <summary>
    //    /// 将源对象映射到目标对象
    //    /// </summary>
    //    /// <typeparam name="TDestination">目标类型</typeparam>
    //    /// <param name="source">源对象</param>
    //    /// <returns></returns>
    //    public static TDestination MapTo<TDestination>(this object source) where TDestination : new()
    //    {
    //        return MapTo(source, new TDestination());
    //    }

    //    /// <summary>
    //    /// 将源对象映射到目标对象
    //    /// </summary>
    //    /// <typeparam name="TDestination">目标类型</typeparam>
    //    /// <param name="source">源对象</param>
    //    /// <param name="destination">目标对象</param>
    //    /// <returns></returns>
    //    private static TDestination MapTo<TDestination>(object source, TDestination destination)
    //    {
    //        if (source == null)
    //        {
    //            throw new ArgumentNullException("source is null");
    //        }
    //        if (destination == null)
    //        {
    //            throw new ArgumentNullException("destination is null");
    //        }
    //        var sourceType = GetType(source);
    //        var destinationType = GetType(destination);
    //        var map = GetMap(sourceType, destinationType);
    //        if (map != null)
    //        {
    //            return AutoMapper.Mapper.Map(source, destination);
    //        }
    //        lock (Sync)
    //        {
    //            map = GetMap(sourceType, destinationType);
    //            if (map != null)
    //            {
    //                return AutoMapper.Mapper.Map(source, destination);
    //            }
    //            InitMaps(sourceType, destinationType);
    //        }
    //        return AutoMapper.Mapper.Map(source, destination);
    //    }

    //    /// <summary>
    //    /// 获取映射配置
    //    /// </summary>
    //    /// <param name="sourceType">源类型</param>
    //    /// <param name="destinationType">目标类型</param>
    //    /// <returns></returns>
    //    private static AutoMapper.TypeMap GetMap(Type sourceType, Type destinationType)
    //    {
    //        try
    //        {
    //            return AutoMapper.Mapper.Configuration.FindTypeMapFor(sourceType, destinationType);
    //        }
    //        catch (InvalidOperationException)
    //        {
    //            lock (Sync)
    //            {
    //                try
    //                {
    //                    return AutoMapper.Mapper.Configuration.FindTypeMapFor(sourceType, destinationType);
    //                }
    //                catch (InvalidOperationException)
    //                {
    //                    InitMaps(sourceType, destinationType);
    //                }
    //                return AutoMapper.Mapper.Configuration.FindTypeMapFor(sourceType, destinationType);
    //            }
    //        }
    //    }

    //    /// <summary>
    //    /// 获取类型
    //    /// </summary>
    //    /// <param name="obj">对象</param>
    //    /// <returns></returns>
    //    private static Type GetType(object obj)
    //    {
    //        var type = obj.GetType();
    //        if (obj is System.Collections.IEnumerable == false)
    //        {
    //            return type;
    //        }
    //        if (type.IsArray)
    //        {
    //            return type.GetElementType();
    //        }
    //        var genericArgumentsTypes = type.GetTypeInfo().GetGenericArguments();
    //        if (genericArgumentsTypes == null || genericArgumentsTypes.Length == 0)
    //        {
    //            throw new ArgumentException("泛型类型参数不能为空");
    //        }
    //        return genericArgumentsTypes[0];
    //    }

    //    /// <summary>
    //    /// 初始化映射配置
    //    /// </summary>
    //    /// <param name="sourceType">源类型</param>
    //    /// <param name="destinationType">目标类型</param>
    //    private static void InitMaps(Type sourceType, Type destinationType)
    //    {
    //        try
    //        {
    //            var maps = AutoMapper.Mapper.Configuration.GetAllTypeMaps();
    //            AutoMapper.Mapper.Initialize(config =>
    //            {
    //                ClearConfig();
    //                foreach (var item in maps)
    //                {
    //                    config.CreateMap(item.SourceType, item.DestinationType);
    //                }
    //                config.CreateMap(sourceType, destinationType);
    //            });
    //        }
    //        catch (InvalidOperationException)
    //        {
    //            AutoMapper.Mapper.Initialize(config =>
    //            {
    //                config.CreateMap(sourceType, destinationType);
    //            });
    //        }
    //    }

    //    /// <summary>
    //    /// 清空配置
    //    /// </summary>
    //    private static void ClearConfig()
    //    {
    //        var typeMapper = typeof(AutoMapper.Mapper).GetTypeInfo();
    //        var configuration = typeMapper.GetDeclaredField("_configuration");
    //        configuration.SetValue(null, null, BindingFlags.Static, null, CultureInfo.CurrentCulture);
    //    }

    //    #endregion

    //    #region MapToList(将源集合映射到目标列表)

    //    /// <summary>
    //    /// 将源集合映射到目标列表
    //    /// </summary>
    //    /// <typeparam name="TDestination">目标元素类型，范例：Sample，不用加List</typeparam>
    //    /// <param name="source">源集合</param>
    //    /// <returns></returns>
    //    public static List<TDestination> MapToList<TDestination>(this System.Collections.IEnumerable source)
    //    {
    //        return MapTo<List<TDestination>>(source);
    //    }

    //    #endregion
    //}
}
